package tests;

import static org.junit.Assert.*;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import model.MeetingBuilder;
import model.User;
import model.Meeting;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * This class tests the User meetings functionality
 * 
 * @author Sukhjinder K. Narula
 * @since June 2013
 *
 * @version $Revision: 1.0 $
 */
public class TestUserMeetings {

	User user;
	HashMap<String, String> properties;
	List<Meeting> meetings;
	Meeting meeting1, meeting2;
	Timestamp start,end;
	
	/**
	 * This method is called before every test case, it creates a new user, sets its properties and adds two meetings to its
	 * list of meetings.
	 */
	@Before
	public void setUp()
	{
		user=new User("sknarula");
		properties=new HashMap<String,String>();
		properties.put("Id", "1");
		properties.put("Name","Laura");
		start=new Timestamp(new java.util.Date().getTime());
		 end=new Timestamp(new java.util.Date().getTime());
		meeting1 = new MeetingBuilder().setUserId(1).setRevisionId(0).setTopic("meeting 1 topic").setOwner("owner").setLocation("montreal").setStart(start)
				.setEnd(end).setAttendees("Attendee1, 2, 3, 4 ").setDescription("some test description").build();
		meeting1.setId(1);
		meeting2 =  new MeetingBuilder().setUserId(1).setRevisionId(0).setTopic("meeting 2 topic").setOwner("owner").setLocation("toronto").setStart(new Timestamp(new java.util.Date().getTime()))
				.setEnd(new Timestamp(new java.util.Date().getTime())).setAttendees("Attendee1, 2, 4 ").setDescription("some more description").build();
		meeting2.setId(2);
		meetings = new ArrayList<Meeting>();
		meetings.add(meeting1);
		meetings.add(meeting2);
		
		user.setMeetings(meetings);		
	}
	
	/**
	 * This method is called after every test case to tear down the user object and force garbage collection.
	 */
	@After
	public void tearDown()
	{
		user=null;
		System.gc();
	}
	
	/**
	 * This test ensures that given an id, the get meeting method returns the correct object
	 */
	@Test
	public void testGetMeetingById() {
		Meeting result = user.getMeeting(1);
		assertEquals(result, meeting1);
	}
	
	/**
	 * This test ensures that given an key, the get meeting method returns the correct object
	 */
	@Test
	public void testGetMeetingByTopic() {
		List<Meeting> result = user.getMeeting("meeting 2 topic");
		assertEquals(1, result.size());
	}
	
	/**
	 * This test case tests the getMeetings method by ensuring that the size of the list of meetings equals to the one specified.
	 */
	@Test
	public void testGetMeetingsBySize() {
		List<Meeting> result=user.getMeetings();
		assertEquals(2,result.size());
	}

	/**
	 * This test ensures that transfer object for meeting is created appropriately
	 */
	@Test
	public void testGetTransferObjectToGetMeetingHashMap() {
		@SuppressWarnings("serial")
		HashMap<String, String> meetingTransferObject = new HashMap<String, String>(){{
			put("Id", String.valueOf(2));
			put("UserId", String.valueOf(1));
			put("Topic", "meeting 2 topic");
			put("C_Topic", "meeting 2 topic");
			put("Location", "toronto");
			put("C_Location", "toronto");
			put("Start", String.valueOf(meeting2.getStart()));
			put("C_Start", String.valueOf(meeting2.getStart()));
			put("End", String.valueOf(meeting2.getEnd()));
			put("C_End", String.valueOf(meeting2.getEnd()));
			put("Attendees", "Attendee1, 2, 4 ");
			put("C_Attendees", "Attendee1, 2, 4 ");
			put("Description", "some more description");
			put("C_Description", "some more description");
		}};
		
		assertEquals(meetingTransferObject, meeting2.getTransferObject());		
	}
	
	/**
	 * This test ensures that transfer object is created appropriately
	 */
	@Test
	public void testGetTransferObjectToGetEmptyHashMap() {
		HashMap<String, String> meetingTransferObject = new HashMap<String, String>();
		assertFalse(meetingTransferObject.equals(meeting2.getTransferObject()));
	}
	
	/**
	 * This test case tests the getMeetings method by ensuring that the list of the meetings return is equals to whats setup
	 */
	@Test
	public void testGetMeetingsByData() {
		List<Meeting> result=user.getMeetings();
		assertEquals(result,meetings);
	}
	/**
	 * This test case tests the get user id method 
	 */
	@Test
	public void testGetUserId()
	{
		assertEquals(1,meeting1.getUserId());
	}
	/**
	 * This test case tests the set user id method 
	 */
	@Test
	public void testSetUserId()
	{
		meeting1.setUserId(2);
		assertEquals(2,meeting1.getUserId());
	}

	/**
	 * This test case tests the set topic method
	 */
	@Test
	public void testSetTopic()
	{
		meeting1.setTopic("new topic");
		assertEquals("new topic",meeting1.getTopic());
	}
	

	/**
	 * This test case tests the get location method
	 */
	@Test
	public void testGetLocation()
	{
		
		assertEquals("montreal",meeting1.getLocation());
	}
	
	/**
	 * This test case tests the set location method
	 */
	@Test
	public void testSetLocation()
	{
		meeting1.setLocation("new location");
		assertEquals("new location",meeting1.getLocation());
	}
	
	/**
	 * This test case tests the get start method
	 */
	@Test
	public void testGetStart()
	{
		
		assertEquals(start,meeting1.getStart());
	}

	/**
	 * This test case tests the set start method
	 */
	@Test
	public void testSetStart()
	{
		start=new Timestamp(new java.util.Date().getTime());
		meeting1.setStart(start);
		
		assertEquals(start,meeting1.getStart());
	}
	
	
	/**
	 * This test case tests the get end method
	 */
	@Test
	public void testGetEnd()
	{
		
		assertEquals(end,meeting1.getEnd());
	}

	/**
	 * This test case tests the set end method
	 */
	@Test
	public void testSetEnd()
	{
		end=new Timestamp(new java.util.Date().getTime());
		meeting1.setEnd(end);
		assertEquals(end,meeting1.getEnd());
	}
	
	/**
	 * This test case tests the get attendees method
	 */
	@Test
	public void testGetAttendees()
	{

		assertEquals("Attendee1, 2, 3, 4 ",meeting1.getAttendees());
	}
	
	/**
	 * This test case tests the set attendees method
	 */
	@Test
	public void testSetAttendees()
	{
		meeting1.setAttendees("new attendees");
		assertEquals("new attendees",meeting1.getAttendees());
	}
	
	/**
	 * This test case tests the get description method
	 */
	@Test
	public void testGetDescription()
	{

		assertEquals("some test description",meeting1.getDescription());
	}
	
	/**
	 * This test case tests the set description method
	 */
	@Test
	public void testSetDescription()
	{
		meeting1.setDescription("new description");
		assertEquals("new description",meeting1.getDescription());
	}
	
	/**
	 * This test case tests the get transfer object method
	 */
	@Test
	public void testGetTransferObject()
	{
		HashMap<String, String> result = new HashMap<String, String>();
		result=meeting1.getTransferObject();
		assertEquals(14,result.size());
		assertNotNull(result);
	}
	
	/**
	 * This test case tests the get owner method
	 */
	@Test
	public void testGetOwner()
	{
		assertTrue("owner".equals(meeting1.getOwner()));
	}

	/**
	 * This test case tests the set owner method
	 */
	@Test
	public void testSetOwner()
	{
		meeting1.setOwner("owner 2");
		assertTrue("owner 2".equals(meeting1.getOwner()));
	}
	
	/**
	 * This test case tests the get revision id method
	 */
	@Test
	public void testGetRevisionId()
	{
		assertEquals(0,meeting1.getRevisionId());
	}
	/**
	 * This test case tests the set revision id method
	 */
	@Test
	public void testSetRevisionId()
	{
		meeting1.setRevisionId(2);
		assertEquals(2,meeting1.getRevisionId());
	}
	/**
	 * This test case tests the set copy location method
	 */
	@Test
	public void testSetCopyLocation()
	{
		meeting1.setC_location("location");
		assertEquals("location",meeting1.getC_location());
		}
	/**
	 * This test case tests the get copy location method
	 */
	@Test
	public void testGetCopyLocation()
	{
		assertEquals("montreal",meeting1.getC_location());
	}
	/**
	 * This test case tests the has same dates method
	 */
	@Test
	public void testHasSameDates()
	{
		assertTrue(meeting1.hasSameDates(meeting1));
	}
	
	/**
	 * This test case tests the dates overlap method
	 */
	@Test
	public void testDatesOverlap()
	{
		assertFalse(meeting1.datesOverLap(meeting2));
	}
	/**
	 * This test case tests the get topic method
	 */
	@Test
	public void testGetCTopic()
	{
		assertEquals("meeting 1 topic",meeting1.getC_topic());
	}
	/**
	 * This test case tests the set c_topic method
	 */
	@Test
	public void testSetCTopic()
	{
		meeting1.setC_topic("Topic");
		assertEquals("Topic",meeting1.getC_topic());
	}
	/**
	 * This test case tests the set c_start method
	 */
	@Test
	public void testSetCStart()
	{
		start=new Timestamp(new java.util.Date().getTime());
		meeting1.setC_start(start);
		assertTrue(start.compareTo(meeting1.getC_start())==0);
	}
	/**
	 * This test case tests the set c_end method
	 */
	@Test
	public void testSetCEnd()
	{
		end=new Timestamp(new java.util.Date().getTime());
		meeting1.setC_end(end);
		assertTrue(end.compareTo(meeting1.getC_end())==0);
	}
	/**
	 * This test case tests the set c_attendees method
	 */
	@Test
	public void testSetCAttendees()
	{
		meeting1.setC_attendees("new attendees");
		assertEquals("new attendees",meeting1.getC_attendees());
	}
	/**
	 * This test case tests the set c_description method
	 */
	@Test
	public void testSetCDescription()
	{
		meeting1.setC_description("new desc");
		assertEquals("new desc",meeting1.getC_description());
	}
	
}
